package com.mini.mybatis.type;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

/**
 * 类型处理器注册表
 * 管理Java类型和TypeHandler之间的映射关系
 */
public class TypeHandlerRegistry {
    
    /**
     * Java类型到TypeHandler的映射
     */
    private final Map<Class<?>, TypeHandler<?>> typeHandlerMap = new HashMap<>();
    
    /**
     * JDBC类型到TypeHandler的映射
     */
    private final Map<JdbcType, TypeHandler<?>> jdbcTypeHandlerMap = new HashMap<>();
    
    /**
     * 默认的TypeHandler
     */
    private final TypeHandler<Object> unknownTypeHandler = new UnknownTypeHandler();
    
    public TypeHandlerRegistry() {
        // 注册默认的类型处理器
        register(String.class, new StringTypeHandler());
        register(Long.class, new LongTypeHandler());
        register(long.class, new LongTypeHandler());
        
        // 可以继续注册其他类型处理器
        // register(Integer.class, new IntegerTypeHandler());
        // register(Boolean.class, new BooleanTypeHandler());
        // ...
    }
    
    /**
     * 注册类型处理器
     * @param javaType Java类型
     * @param handler 类型处理器
     */
    public <T> void register(Class<T> javaType, TypeHandler<? extends T> handler) {
        typeHandlerMap.put(javaType, handler);
    }
    
    /**
     * 注册JDBC类型处理器
     * @param jdbcType JDBC类型
     * @param handler 类型处理器
     */
    public void register(JdbcType jdbcType, TypeHandler<?> handler) {
        jdbcTypeHandlerMap.put(jdbcType, handler);
    }
    
    /**
     * 获取类型处理器
     * @param type Java类型
     * @return 类型处理器
     */
    @SuppressWarnings("unchecked")
    public <T> TypeHandler<T> getTypeHandler(Class<T> type) {
        TypeHandler<?> handler = typeHandlerMap.get(type);
        if (handler == null) {
            // 如果没有找到精确匹配的处理器，返回默认处理器
            return (TypeHandler<T>) unknownTypeHandler;
        }
        return (TypeHandler<T>) handler;
    }
    
    /**
     * 获取JDBC类型处理器
     * @param jdbcType JDBC类型
     * @return 类型处理器
     */
    public TypeHandler<?> getTypeHandler(JdbcType jdbcType) {
        return jdbcTypeHandlerMap.get(jdbcType);
    }
    
    /**
     * 检查是否有指定类型的处理器
     * @param javaType Java类型
     * @return 是否存在处理器
     */
    public boolean hasTypeHandler(Class<?> javaType) {
        return typeHandlerMap.containsKey(javaType) || javaType.isPrimitive();
    }
    
    /**
     * 未知类型处理器
     * 用于处理没有注册的类型
     */
    private static class UnknownTypeHandler extends BaseTypeHandler<Object> {
        
        @Override
        public void setNonNullParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType) throws SQLException {
            ps.setObject(i, parameter);
        }
        
        @Override
        public Object getNullableResult(ResultSet rs, String columnName) throws SQLException {
            return rs.getObject(columnName);
        }
        
        @Override
        public Object getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
            return rs.getObject(columnIndex);
        }
        
        @Override
        public Object getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
            return cs.getObject(columnIndex);
        }
    }
}